#include <arpa/inet.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

/**
 * 检查网络连通性
 * @param host 
 * @param port
 * @param timeout_sec 单位秒
 */
bool checkPingConnectivity(const char *host, uint16_t port, int timeout_sec) {
	struct addrinfo hints = {0}, *res = NULL, *p;
	hints.ai_family = AF_UNSPEC;	 // IPv4 或 IPv6
	hints.ai_socktype = SOCK_STREAM; // TCP

	char port_str[6];
	snprintf(port_str, sizeof(port_str), "%d", port);

	if (getaddrinfo(host, port_str, &hints, &res) != 0) {
		return false; // DNS 解析失败
	}

	bool connected = false;

	for (p = res; p != NULL; p = p->ai_next) {
		int sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (sock < 0)
			continue;

		// 设置超时
		struct timeval timeout;
		timeout.tv_sec = timeout_sec;
		timeout.tv_usec = 0;
		setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
		setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));

		if (connect(sock, p->ai_addr, p->ai_addrlen) == 0) {
			connected = true;
			close(sock);
			break;
		}
		close(sock);
	}

	freeaddrinfo(res);
	return connected;
}
